home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 4
/
Aminet 4 - November 1994.iso
/
aminet
/
dev
/
obero
/
oberon_lib.lha
/
oberon-a
/
source1.lha
/
source
/
Amiga
/
Utility.mod
< prev
next >
Wrap
Text File
|
1994-08-08
|
22KB
|
731 lines
(**************************************************************************
$RCSfile: Utility.mod $
Description: Interface to utility.library
Created by: fjc (Frank Copeland)
$Revision: 3.2 $
$Author: fjc $
$Date: 1994/08/08 00:45:05 $
Includes Release 40.15
(C) Copyright 1985-1993 Commodore-Amiga, Inc.
All Rights Reserved
Oberon-A interface Copyright © 1994, Frank Copeland.
This file is part of the Oberon-A Interface.
See Oberon-A.doc for conditions of use and distribution.
***************************************************************************)
MODULE Utility;
(*
** $C- CaseChk $I- IndexChk $L+ LongAdr $N- NilChk
** $P- PortableCode $R- RangeChk $S- StackChk $T- TypeChk
** $V- OvflChk $Z- ZeroVars
*)
IMPORT E := Exec, SYS := SYSTEM;
(*-- Pointer declarations ---------------------------------------------*)
TYPE
ClockDataPtr * = CPOINTER TO ClockData;
HookPtr * = CPOINTER TO Hook;
TagItemPtr * = CPOINTER TO TagItem;
NamedObjectPtr * = CPOINTER TO NamedObject;
(*-- Library definitions ----------------------------------------------*)
(*
** $VER: date.h 39.1 (20.1.92)
**
** Date conversion routines ClockData definition.
*)
TYPE
ClockData* = RECORD
sec * : E.UWORD;
min * : E.UWORD;
hour * : E.UWORD;
mday * : E.UWORD;
month* : E.UWORD;
year * : E.UWORD;
wday * : E.UWORD;
END; (* ClockData *)
(*
** $VER: hooks.h 39.2 (16.6.93)
**
** callback hooks
*)
TYPE
(* new standard hook structure *)
HookFunc * =
PROCEDURE (hook : HookPtr; object : E.APTR; message : E.APTR) : E.APTR;
AsmHookFunc * = PROCEDURE () : E.APTR;
(*
*** Oberon-A Note ***
Oberon-A does not allow register parameters for normal procedures,
so if you use an AsmHookFunc, you must use SYS.GETREG to access
the parameters. e.g:
PROCEDURE MyHookFunc () : E.APTR
VAR hook : HookPtr; object : E.APTR; message : E.APTR;
BEGIN
SYS.GETREG (8, hook);
SYS.GETREG (10, object);
SYS.GETREG (9, message);
...
END MyHookFunc;
*)
Hook* = RECORD (E.MinNode)
entry * : AsmHookFunc; (* assembler entry point *)
subEntry* : HookFunc; (* often HLL entry point *)
data * : E.APTR; (* owner specific *)
END; (* Hook *)
(*
* Hook calling conventions:
* A0 - pointer to hook data structure itself
* A1 - pointer to parameter structure ("message") typically
* beginning with a longword command code, which makes
* sense in the context in which the hook is being used.
* A2 - Hook specific address data ("object," e.g, GadgetInfo)
*
* Control will be passed to the routine hEntry. For many
* High-Level Languages (HLL), this will be an assembly language
* stub which pushes registers on the stack, does other setup,
* and then calls the function at hSubEntry.
*
* The C standard receiving code is:
* CDispatcher( hook, object, message )
* STRUCT Hook *hook;
* APTR object;
* APTR message;
*
* NOTE that register natural order differs from this convention
* for C parameter order, which is A0,A2,A1.
*
* The assembly language stub for "vanilla" C parameter conventions
* could be:
_hookEntry:
move.l a1,-(sp) ; push message packet pointer
move.l a2,-(sp) ; push object pointer
move.l a0,-(sp) ; push hook pointer
move.l h_SubEntry(a0),a0 ; fetch C entry point ...
jsr (a0) ; ... and call it
lea 12(sp),sp ; fix stack
rts
* with this function as your interface stub, you can write
* a Hook setup function as:
SetupHook( hook, c_function, userdata )
STRUCT Hook *hook;
ULONG ( *c_function)();
VOID *userdata;
{
ULONG ( *hookEntry)();
hook->h_Entry = hookEntry;
hook->h_SubEntry = c_function;
hook->h_Data = userdata;
}
* with Lattice C pragmas, you can put the C function in the
* h_Entry field directly if you declare the function:
ULONG __saveds __asm
CDispatcher( register __a0 STRUCT Hook *hook,
register __a2 VOID *object,
register __a1 ULONG *message );
*
****)
(*
** $VER: tagitem.h 40.1 (19.7.93)
**
** extended specification mechanism
*)
(*****************************************************************************)
(* Tags are a general mechanism of extensible data arrays for parameter
* specification and property inquiry. In practice, tags are used in arrays,
* or chain of arrays.
*
*)
TYPE
Tag * = SYS.LONGWORD;
TagItem* = RECORD
tag* : E.ULONG;
data* : Tag;
END; (* TagItem *)
TagListPtr * = CPOINTER TO ARRAY MAX (INTEGER) OF TagItem;
CONST
(* constants for Tag.tag, control tag values *)
tagDone * = 0; (* terminates array of TagItems. tiData unused *)
tagEnd * = tagDone;
tagIgnore* = 1; (* ignore this item, not end of array *)
tagMore * = 2; (* tiData is pointer to another array of TagItems
* note that this tag terminates the current array
*)
tagSkip * = 3; (* skip this and the next tiData items *)
(* differentiates user tags from control tags *)
tagUser * = 80000000H;
(* If the tagUser bit is set in a tag number, it tells utility.library that
* the tag is not a control tag (like tagDone, tagIgnore, tagMore) and is
* instead an application tag. "USER" means a client of utility.library in
* general, including system code like Intuition or ASL, it has nothing to do
* with user code.
*)
(*****************************************************************************)
(* Tag filter logic specifiers for use with FilterTagItems() *)
tagFilterAND * = 0; (* exclude everything but filter hits *)
tagFilterNOT * = 1; (* exclude only filter hits *)
(*****************************************************************************)
(* Mapping types for use with MapTags() *)
mapRemoveNotFound * = 0; (* remove tags that aren't in mapList *)
mapKeepNotFound * = 1; (* keep tags that aren't in mapList *)
(*****************************************************************************)
(*
** $VER: name.h 39.5 (11.8.93)
**
** Namespace definitions
**)
(*****************************************************************************)
TYPE
(* The named object structure *)
NamedObject * = RECORD
object * : E.APTR; (* Your pointer, for whatever you want *)
END;
CONST
(* Tags for AllocNamedObject() *)
anoNameSpace * = 4000; (* Tag to define namespace *)
anoUserSpace * = 4001; (* tag to define userspace *)
anoPriority * = 4002; (* tag to define priority *)
anoFlags * = 4003; (* tag to define flags *)
(* Flags for tag anoFlags *)
nsNodups * = 0; (* Default allow duplicates *)
nsCase * = 1; (* Default to caseless... *)
(*****************************************************************************)
(*
** $VER: pack.h 39.3 (10.2.93)
**
** Control attributes for Pack/UnpackStructureTags()
*)
(*****************************************************************************)
(* PackTable definition:
*
* The PackTable is a simple array of LONGWORDS that are evaluated by
* PackStructureTags() and UnpackStructureTags().
*
* The table contains compressed information such as the tag offset from
* the base tag. The tag offset has a limited range so the base tag is
* defined in the first longword.
*
* After the first longword, the fields look as follows:
*
* +--------- 1 = signed, 0 = unsigned (for bits, 1=inverted boolean)
* |
* | +------ 00 = Pack/Unpack, 10 = Pack, 01 = Unpack, 11 = special
* | / \
* | | | +-- 00 = Byte, 01 = Word, 10 = Long, 11 = Bit
* | | | / \
* | | | | | /----- For bit operations: 1 = TAG_EXISTS is TRUE
* | | | | | |
* | | | | | | /-------------------- Tag offset from base tag value
* | | | | | | | \
* m n n o o p q q q q q q q q q q r r r s s s s s s s s s s s s s
* \ | | |
* Bit offset (for bit operations) ----/ | |
* \ |
* Offset into data structure -----------------------------------/
*
* A -1 longword signifies that the next longword will be a new base tag
*
* A 0 longword signifies that it is the end of the pack table.
*
* What this implies is that there are only 13-bits of address offset
* and 10 bits for tag offsets from the base tag. For most uses this
* should be enough, but when this is not, either multiple pack tables
* or a pack table with extra base tags would be able to do the trick.
* The goal here was to make the tables small and yet flexible enough to
* handle most cases.
*)
CONST
pstSigned * = 31;
pstUnpack * = 30; (* Note that these are active low... *)
pstPack * = 29; (* Note that these are active low... *)
pstExists * = 26; (* Tag exists bit true flag hack... *)
(*****************************************************************************)
CONST
pkCtrlPackUnpack * = 000000000H;
pkCtrlPackOnly * = 040000000H;
pkCtrlUnpackOnly * = 020000000H;
pkCtrlBYTE * = 080000000H;
pkCtrlWORD * = 088000000H;
pkCtrlLONG * = 090000000H;
pkCtrlUBYTE * = 000000000H;
pkCtrlUWORD * = 008000000H;
pkCtrlULONG * = 010000000H;
pkCtrlBit * = 018000000H;
pkCtrlFlipBit * = 098000000H;
(*
The following C macros are included for information only. They may be
implemented as procedures in the future if there is any demand for it.
(*****************************************************************************)
(* Macros used by the next batch of macros below. Normally, you don't use
* this batch directly. Then again, some folks are wierd
*)
#define PK_BITNUM1(flg) ((flg) == 0x01 ? 0 : (flg) == 0x02 ? 1 : (flg) == 0x04 ? 2 : (flg) == 0x08 ? 3 : (flg) == 0x10 ? 4 : (flg) == 0x20 ? 5 : (flg) == 0x40 ? 6 : 7)
#define PK_BITNUM2(flg) ((flg < 0x100 ? PK_BITNUM1(flg) : 8+PK_BITNUM1(flg >> 8)))
#define PK_BITNUM(flg) ((flg < 0x10000 ? PK_BITNUM2(flg) : 16+PK_BITNUM2(flg >> 16)))
#define PK_WORDOFFSET(flg) ((flg) < 0x100 ? 1 : 0)
#define PK_LONGOFFSET(flg) ((flg) < 0x100 ? 3 : (flg) < 0x10000 ? 2 : (flg) < 0x1000000 ? 1 : 0)
#define PK_CALCOFFSET(type,field) ((ULONG)(&((struct type * )0)->field))
(*****************************************************************************)
(* Some handy dandy macros to easily create pack tables
*
* Use PACK_STARTTABLE() at the start of a pack table. You pass it the
* base tag value that will be handled in the following chunk of the pack
* table.
*
* PACK_ENDTABLE() is used to mark the end of a pack table.
*
* PACK_NEWOFFSET() lets you change the base tag value used for subsequent
* entries in the table
*
* PACK_ENTRY() lets you define an entry in the pack table. You pass it the
* base tag value, the tag of interest, the type of the structure to use,
* the field name in the structure to affect and control bits (combinations of
* the various PKCTRL_XXX bits)
*
* PACK_BYTEBIT() lets you define a bit-control entry in the pack table. You
* pass it the same data as PACK_ENTRY, plus the flag bit pattern this tag
* affects. This macro should be used when the field being affected is byte
* sized.
*
* PACK_WORDBIT() lets you define a bit-control entry in the pack table. You
* pass it the same data as PACK_ENTRY, plus the flag bit pattern this tag
* affects. This macro should be used when the field being affected is word
* sized.
*
* PACK_LONGBIT() lets you define a bit-control entry in the pack table. You
* pass it the same data as PACK_ENTRY, plus the flag bit pattern this tag
* affects. This macro should be used when the field being affected is longword
* sized.
*
* EXAMPLE:
*
* ULONG packTable[] =
* {
* PACK_STARTTABLE(GA_Dummy),
* PACK_ENTRY(GA_Dummy,GA_Left,Gadget,LeftEdge,PKCTRL_WORD|PKCTRL_PACKUNPACK),
* PACK_ENTRY(GA_Dummy,GA_Top,Gadget,TopEdge,PKCTRL_WORD|PKCTRL_PACKUNPACK),
* PACK_ENTRY(GA_Dummy,GA_Width,Gadget,Width,PKCTRL_UWORD|PKCTRL_PACKUNPACK),
* PACK_ENTRY(GA_Dummy,GA_Height,Gadget,Height,PKCTRL_UWORD|PKCTRL_PACKUNPACK),
* PACK_WORDBIT(GA_Dummy,GA_RelVerify,Gadget,Activation,PKCTRL_BIT|PKCTRL_PACKUNPACK,GACT_RELVERIFY)
* PACK_ENDTABLE
* };
*)
#define PACK_STARTTABLE(tagbase) (tagbase)
#define PACK_NEWOFFSET(tagbase) (-1L),(tagbase)
#define PACK_ENDTABLE 0
#define PACK_ENTRY(tagbase,tag,type,field,control) (control | ((tag-tagbase) << 16L) | PK_CALCOFFSET(type,field))
#define PACK_BYTEBIT(tagbase,tag,type,field,control,flags) (control | ((tag-tagbase) << 16L) | PK_CALCOFFSET(type,field) | (PK_BITNUM(flags) << 13L))
#define PACK_WORDBIT(tagbase,tag,type,field,control,flags) (control | ((tag-tagbase) << 16L) | (PK_CALCOFFSET(type,field)+PK_WORDOFFSET(flags)) | ((PK_BITNUM(flags)&7) << 13L))
#define PACK_LONGBIT(tagbase,tag,type,field,control,flags) (control | ((tag-tagbase) << 16L) | (PK_CALCOFFSET(type,field)+PK_LONGOFFSET(flags)) | ((PK_BITNUM(flags)&7) << 13L))
*)
(*****************************************************************************)
(*
** $VER: utility.h 39.2 (18.9.92)
*)
CONST
name * = "utility.library";
TYPE
UtilityBasePtr* = CPOINTER TO UtilityBase;
UtilityBase * = RECORD (E.Library)
language * : E.UBYTE;
reserved * : E.UBYTE;
END;
(*-- Library Base variable --------------------------------------------*)
VAR
base* : UtilityBasePtr;
(*-- Library Functions ------------------------------------------------*)
(*
** $VER: utility_protos.h 39.12 (10.2.93)
*)
(*--- functions in V36 or higher (Release 2.0) ---*)
(* *** TagItem FUNCTIONS *** *)
LIBCALL (base : UtilityBasePtr) FindTagItemA*
( tagVal [0] : E.ULONG;
tagList [8] : ARRAY OF TagItem )
: TagItemPtr;
-30;
LIBCALL (base : UtilityBasePtr) FindTagItem*
( tagVal [0] : E.ULONG;
tagList [8] : TagListPtr )
: TagItemPtr;
-30;
LIBCALL (base : UtilityBasePtr) GetTagDataPA*
( tagVal [0] : E.ULONG;
defaultVal [1] : E.APTR;
tagList [8] : ARRAY OF TagItem )
: E.APTR;
-36;
LIBCALL (base : UtilityBasePtr) GetTagDataA*
( tagVal [0] : E.ULONG;
defaultVal [1] : E.ULONG;
tagList [8] : ARRAY OF TagItem )
: E.ULONG;
-36;
LIBCALL (base : UtilityBasePtr) GetTagDataP*
( tagVal [0] : E.ULONG;
defaultVal [1] : E.APTR;
tagList [8] : TagListPtr )
: E.APTR;
-36;
LIBCALL (base : UtilityBasePtr) GetTagData*
( tagVal [0] : E.ULONG;
defaultVal [1] : E.ULONG;
tagList [8] : TagListPtr )
: E.ULONG;
-36;
LIBCALL (base : UtilityBasePtr) PackBoolTagsA*
( initialFlags [0] : SET;
tagList [8] : ARRAY OF TagItem;
boolMap [9] : ARRAY OF TagItem )
: SET;
-42;
LIBCALL (base : UtilityBasePtr) PackBoolTags*
( initialFlags [0] : SET;
tagList [8] : TagListPtr;
boolMap [9] : ARRAY OF TagItem )
: SET;
-42;
LIBCALL (base : UtilityBasePtr) NextTagItem*
( VAR tagListPtr [8] : TagItemPtr )
: TagItemPtr;
-48;
LIBCALL (base : UtilityBasePtr) FilterTagChanges*
( newTagList [8] : ARRAY OF TagItem;
oldTagList [9] : ARRAY OF TagItem;
apply [0] : BOOLEAN );
-54;
LIBCALL (base : UtilityBasePtr) MapTags*
( tagList [8] : ARRAY OF TagItem;
mapList [9] : ARRAY OF TagItem;
includeMiss [0] : LONGINT );
-60;
LIBCALL (base : UtilityBasePtr) AllocateTagItems*
( numItems [0] : E.ULONG )
: TagListPtr;
-66;
LIBCALL (base : UtilityBasePtr) CloneTagItemsA*
( tagList [8] : ARRAY OF TagItem )
: TagListPtr;
-72;
LIBCALL (base : UtilityBasePtr) CloneTagItems*
( tagList [8] : TagListPtr )
: TagListPtr;
-72;
LIBCALL (base : UtilityBasePtr) FreeTagItems*
( tagList [8] : TagListPtr );
-78;
LIBCALL (base : UtilityBasePtr) RefreshTagItemClones*
( cloneList [8] : ARRAY OF TagItem;
origList [9] : ARRAY OF TagItem );
-84;
LIBCALL (base : UtilityBasePtr) TagInArrayA*
( tagVal [0] : E.ULONG;
tagArray [8] : ARRAY OF TagItem )
: BOOLEAN;
-90;
LIBCALL (base : UtilityBasePtr) TagInArray*
( tagVal [0] : E.ULONG;
tagArray [8] : TagListPtr )
: BOOLEAN;
-90;
LIBCALL (base : UtilityBasePtr) FilterTagItems*
( tagList [8] : ARRAY OF TagItem;
filterArray [9] : ARRAY OF TagItem;
logic [0] : LONGINT )
: LONGINT;
-96;
(* *** HOOK FUNCTIONS *** * *)
LIBCALL (base : UtilityBasePtr) CallHookPkt*
( hook [8] : HookPtr;
object [10] : E.APTR;
paramPacket [9] : E.APTR )
: E.ULONG;
-102;
(* *** DATE FUNCTIONS *** * *)
LIBCALL (base : UtilityBasePtr) Amiga2Date*
( amigaTime [0] : E.ULONG;
VAR date [8] : ClockData );
-120;
LIBCALL (base : UtilityBasePtr) Date2Amiga*
( VAR date [8] : ClockData )
: E.ULONG;
-126;
LIBCALL (base : UtilityBasePtr) CheckDate*
( VAR date [8] : ClockData )
: E.ULONG;
-132;
(* *** 32 BIT MATH FUNCTIONS *** * *)
LIBCALL (base : UtilityBasePtr) SMult32*
( factor1 [0] : LONGINT;
factor2 [1] : LONGINT )
: LONGINT;
-138;
LIBCALL (base : UtilityBasePtr) UMult32*
( factor1 [0] : E.ULONG;
factor2 [1] : E.ULONG )
: E.ULONG;
-144;
(* NOTE: Quotient:Remainder returned in d0:d1 *)
LIBCALL (base : UtilityBasePtr) SDivMod32*
( dividend [0] : LONGINT;
divisor [1] : LONGINT )
: LONGINT;
-150;
LIBCALL (base : UtilityBasePtr) UDivMod32*
( dividend [0] : E.ULONG;
divisor [1] : E.ULONG )
: E.ULONG;
-156;
(*--- functions in V37 or higher (Release 2.04) ---*)
(* *** International string routines *** *)
LIBCALL (base : UtilityBasePtr) Stricmp*
( string1 [8] : ARRAY OF CHAR;
string2 [9] : ARRAY OF CHAR )
: LONGINT;
-162;
LIBCALL (base : UtilityBasePtr) Strnicmp*
( string1 [8] : ARRAY OF CHAR;
string2 [9] : ARRAY OF CHAR;
length [0] : LONGINT )
: LONGINT;
-168;
LIBCALL (base : UtilityBasePtr) ToUpper*
( character [0] : CHAR )
: CHAR;
-174;
LIBCALL (base : UtilityBasePtr) ToLower*
( character [0] : CHAR )
: CHAR;
-180;
(*--- functions in V39 or higher (Release 3) ---*)
(* More tag Item functions *)
LIBCALL (base : UtilityBasePtr) ApplyTagChanges *
( list [8] : ARRAY OF TagItem; changeList [9] : ARRAY OF TagItem );
-186;
(* 64 bit integer muliply functions. The results are 64 bit quantities *)
(* returned in D0 and D1 *)
LIBCALL (base : UtilityBasePtr) SMult64 *
( arg1 [0] : LONGINT; arg2 [1] : LONGINT )
: LONGINT;
-198;
LIBCALL (base : UtilityBasePtr) UMult64 *
( arg1 [0] : E.ULONG; arg2 [1] : E.ULONG )
: E.ULONG;
-204;
(* Structure to Tag and Tag to Structure support routines *)
LIBCALL (base : UtilityBasePtr) PackStructureTagsA *
( pack [8] : E.APTR; packTable [9] : ARRAY OF E.ULONG;
tagList [10] : ARRAY OF TagItem )
: E.ULONG;
-210;
LIBCALL (base : UtilityBasePtr) PackStructureTags *
( pack [8] : E.APTR; packTable [9] : ARRAY OF E.ULONG;
tagList [10] : TagListPtr )
: E.ULONG;
-210;
LIBCALL (base : UtilityBasePtr) UnpackStructureTagsA *
( pack [8] : E.APTR; packTable [9] : ARRAY OF E.ULONG;
tagList [10] : ARRAY OF TagItem )
: E.ULONG;
-216;
LIBCALL (base : UtilityBasePtr) UnpackStructureTags *
( pack [8] : E.APTR; packTable [9] : ARRAY OF E.ULONG;
tagList [10] : TagListPtr )
: E.ULONG;
-216;
(* New, object-oriented NameSpaces *)
LIBCALL (base : UtilityBasePtr) AddNamedObject *
( nameSpace [8] : NamedObjectPtr; object [9] : NamedObjectPtr )
: BOOLEAN;
-222;
LIBCALL (base : UtilityBasePtr) AllocNamedObjectA *
( name [8] : ARRAY OF CHAR; tagList [9] : ARRAY OF TagItem )
: NamedObjectPtr;
-228;
LIBCALL (base : UtilityBasePtr) AllocNamedObject *
( name [8] : ARRAY OF CHAR; tagList [9].. : Tag )
: NamedObjectPtr;
-228;
LIBCALL (base : UtilityBasePtr) AttemptRemNamedObject *
( object [8] : NamedObjectPtr )
: BOOLEAN;
-234;
LIBCALL (base : UtilityBasePtr) FindNamedObject *
( nameSpace [8] : NamedObjectPtr; name [9] : ARRAY OF CHAR;
lastObject [10] : NamedObjectPtr )
: NamedObjectPtr;
-240;
LIBCALL (base : UtilityBasePtr) FreeNamedObject *
( object [8] : NamedObjectPtr );
-246;
LIBCALL (base : UtilityBasePtr) NamedObjectName *
( object [8] : NamedObjectPtr )
: E.STRPTR;
-252;
LIBCALL (base : UtilityBasePtr) ReleaseNamedObject *
( object [8] : NamedObjectPtr );
-258;
LIBCALL (base : UtilityBasePtr) RemNamedObject *
( object [8] : NamedObjectPtr; message [9] : E.MessagePtr );
-264;
(* Unique ID generator *)
LIBCALL (base : UtilityBasePtr) GetUniqueID * ()
: E.ULONG;
-270;
(*-- Library Base variable --------------------------------------------*)
(* $L- *)
(*-----------------------------------*)
PROCEDURE* CloseLib ();
BEGIN (* CloseLib *)
IF base # NIL THEN E.base.CloseLibrary (base) END;
END CloseLib;
(*-----------------------------------*)
PROCEDURE OpenLib * (mustOpen : BOOLEAN);
BEGIN (* OpenLib *)
IF base = NIL THEN
base :=
SYS.VAL (
UtilityBasePtr,
E.base.OpenLibrary (name, E.libraryMinimum));
IF base # NIL THEN SYS.SETCLEANUP (CloseLib)
ELSIF mustOpen THEN HALT (100)
END;
END;
END OpenLib;
BEGIN
base := NIL
END Utility.